package ms.maplestory.boot.connection.netty;

import ms.maplestory.boot.ServerConstants;
import ms.maplestory.boot.connection.Packet;
import ms.maplestory.boot.connection.crypto.Crypto;
import ms.maplestory.boot.connection.opcode.OutHeader;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;

@Slf4j(topic = "[Netty PacketEncoder]")
public class PacketEncoder extends MessageToByteEncoder<Packet> {

    @Override
    protected void encode(ChannelHandlerContext chc, Packet outPacket, ByteBuf bb) {
        byte[] data = outPacket.getData();
        NettyClient c = chc.channel().attr(NettyClient.CLIENT_KEY).get();
        Crypto mCr = chc.channel().attr(NettyClient.CRYPTO_KEY).get();
        if (c != null) {
            if (!OutHeader.isSpamHeader(OutHeader.getOutHeaderByOp(outPacket.getHeader()))) { // 封包输出
                log.debug("" + outPacket);
            }
            byte[] iv = c.getSendIV();
            byte[] head = Crypto.getHeader(data.length, iv);
            c.acquireEncoderState();
            try {
                if (ServerConstants.DECRYPT_DATA_ENABLE) mCr.encryptData(data);
                mCr.crypt(data, iv);
                c.setSendIV(Crypto.getNewIv(iv));
            } finally {
                c.releaseEncodeState();
            }
            bb.writeBytes(head);
        }
        bb.writeBytes(data);
    }
}
